<?php

class Light_Loader
{
    /**
     * @var array
     */
	public static $files = array();

	/**
	 *
	 * @var array
	 */
	public static $classes;

	/**
	 * @var boolean
	 */
	public static $classCacheEnable = false;

	/**
	 * @param string $class
	 * @param boolean $exception
	 * @throws Light_Exception
	 * @return boolean
	 */
	public static function tryLoadClass($class, $exception = true)
	{
	    if (class_exists($class, false) || interface_exists($class, false)) {
	        return true;
	    }

	    if (self::$classCacheEnable === true && self::lookAtClassCache($class) === true) {
	        return true;
	    }

	    if (preg_match('/^(?!Light_)([a-zA-Z_]+)(_Controller_|_Model_|_Helper_|_Service_)/', $class, $match)) {
	        $classParts = explode('_', $class);
	        $classParts[0] = strtolower($classParts[0]);
	        switch ($match[2]) {
	            case '_Controller_':
	                $classParts[1] = 'controllers';
	                $classParts[2] = strtolower($classParts[2]);
	                if ($classParts[2] !== 'admin') {
	                    $classParts[2] = ucfirst($classParts[2]);
	                }
	                break;
	            case '_Model_':
	                $classParts[1] = 'models';
	                break;
	            case '_Helper_':
	                $classParts[1] = 'views';
	                $classParts[2] = 'helpers';
	                break;
                case '_Service_':
                    $classParts[1] = 'services';
                    break;
	        }
	        $file = LIGHT_APPLICATION_PATH . '/modules/' . implode('/', $classParts) . '.php';
	    } else {
	        $file = LIGHT_LIBRARY_PATH . '/' . str_replace('_', '/', $class) . '.php';
	    }

	    if (is_readable($file) === false) {
	        if ($exception === false) {
	            return false;
	        }
	        throw new Light_Exception('File <b>' . $file . '</b> does not exists', 501);
	    }

	    Light_Loader::$files[$class] = $file;

	    require $file;

	    if (!class_exists($class, false) && !interface_exists($class, false)) {
	        if ($exception === false) {
	            return false;
	        }
	        throw new Light_Exception('Class <b>' . $class . '</b> does not exists', 501);
	    }

	    if (self::$classCacheEnable === true) {
	        self::$classes[$class] = str_replace(array('\\', '/'), '/', $file);
	        file_put_contents(LIGHT_APPLICATION_PATH . '/Classes.php', '<?php' . "\n\n" . 'return ' . var_export(self::$classes, true) . ';');
	    }

	    return true;
	}

	/**
	 * @param string $class
	 * @return boolean
	 */
	public static function loadClass($class)
	{
	    return self::tryLoadClass($class, false);
	}

	/**
	 * @param string $class
	 * @return boolean
	 */
	public static function lookAtClassCache($class)
	{
	    if (self::$classes === null) {
	        self::$classes = require LIGHT_APPLICATION_PATH . '/Classes.php';
	    }

	    if (isset(self::$classes[$class])) {
	        Light_Loader::$files[$class] = self::$classes[$class];
	        require self::$classes[$class];
	        return true;
	    }

	    return false;
	}
}